package com.xhy.documents_collection.aop;

import com.xhy.documents_collection.annotations.FileLog;
import com.xhy.documents_collection.annotations.OperLog;
import com.xhy.documents_collection.entity.PO.log.SysLog;
import com.xhy.documents_collection.entity.PO.task.TaskRecord;
import com.xhy.documents_collection.enums.BusinessType;
import com.xhy.documents_collection.holder.UserHolder;
import com.xhy.documents_collection.restrict.RestrictHandler;
import com.xhy.documents_collection.service.FileLogService;
import com.xhy.documents_collection.service.sys.SysLogService;
import com.xhy.documents_collection.service.task.TaskRecordService;
import com.xhy.documents_collection.service.task.TaskService;
import com.xhy.documents_collection.thread_pool.LogThreadPool;
import com.xhy.documents_collection.utils.DeviceUtils;
import com.xhy.documents_collection.utils.IpUtils;
import com.xhy.documents_collection.utils.JwtUtils;
import com.xhy.documents_collection.utils.TransitionByteToCH;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.NamedThreadLocal;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Author: Xhy
 * CreateTime: 2023-03-08 09:40
 */
@Aspect
@Component
public class FileLogAop {

    @Autowired
    HttpServletRequest request;

    @Autowired
    RestrictHandler restrictHandler;

    @Resource
    FileLogService fileLogService;

    @Resource
    TaskRecordService taskRecordService;

    @Resource
    TaskService taskService;

    @Before("@annotation(fileLog)")
    public void before(JoinPoint joinPoint, FileLog fileLog) throws Throwable {
        UserHolder.set(JwtUtils.getMemberIdByJwtToken(request));

    }

    @AfterReturning("@annotation(fileLog)")
    public void after(JoinPoint joinPoint, FileLog fileLog)
    {
        handleLog(joinPoint,fileLog,null);
    }

    @AfterThrowing(value = "@annotation(fileLog)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, FileLog fileLog, Exception e)
    {
        handleLog(joinPoint,fileLog,e);
    }

    private void handleLog(JoinPoint joinPoint,FileLog fileLog, Exception e) {
        BusinessType businessType = fileLog.businessType();

        String title = fileLog.title().name();
        Integer userId = UserHolder.get();
        String ipAddr = IpUtils.getIpAddr(request);
        com.xhy.documents_collection.entity.PO.log.FileLog fileLogObject = new com.xhy.documents_collection.entity.PO.log.FileLog();
        Object[] args = joinPoint.getArgs();
        Integer taskRecordId = null;
        String fileSize = "";
        String fileName = "";
        Object arg = args[0];
        // 下载 从请求参数中获取
        if (businessType == BusinessType.DOWNLOAD){
            // 获取ids
            List<Integer> taskRecordIds = Arrays.asList(arg.toString().split(",")).stream().map(Integer::parseInt).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(taskRecordIds)){
                Long size = taskRecordService.listByIds(taskRecordIds).stream().map(TaskRecord::getFileSize).count();
                fileSize = TransitionByteToCH.getPrintSize(size);
            }
            taskRecordId = taskRecordIds.get(0);
            // 获取记录的任务
            fileName = taskService.getById(taskRecordService.getById(taskRecordId).getTId()).getName();

        }else if (businessType == BusinessType.UPLOAD){
            // 上传 从请求参数中拿file相关参数
            MultipartFile file = (MultipartFile) arg;
            taskRecordId = Integer.parseInt(args[1].toString());
            fileSize = TransitionByteToCH.getPrintSize(file.getSize());
            fileName = file.getOriginalFilename();
        }else {
            // 撤回 从请求参数中获取
            taskRecordId = Integer.parseInt(arg.toString());
            TaskRecord record = taskRecordService.getById(taskRecordId);
            fileSize = TransitionByteToCH.getPrintSize(record.getFileSize());
            fileName = record.getFileName();
        }
        fileLogObject.setOs(DeviceUtils.getOs(request));
        fileLogObject.setUId(userId);
        fileLogObject.setTaskRecordId(taskRecordId);
        fileLogObject.setFileSize(fileSize);
        fileLogObject.setFileName(fileName);
        fileLogObject.setBusinessType(businessType.ordinal());
        fileLogObject.setTitle(title);
        fileLogObject.setIp(ipAddr);
        fileLogObject.setState(true);
        if (e!=null){
            fileLogObject.setState(false);
        }
        try {
            LogThreadPool.addFileLog(fileLogObject);
        }catch (Exception exp){
           exp.printStackTrace();
        }finally {
            UserHolder.clear();
        }
    }
}
